package com.tbit.uqbike.webmanager.business.photo_upload_log.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.tbit.uqbike.object.pojo.Account;
import com.tbit.uqbike.object.pojo.RideLog;
import com.tbit.common.entity.view.PageResult;
import com.tbit.uqbike.webmanager.business.photo_upload_log.dao.log.PhotoUploadLogDao;
import com.tbit.uqbike.webmanager.business.photo_upload_log.object.PhotoUploadLog;
import com.tbit.uqbike.webmanager.business.photo_upload_log.object.vo.PhotoReturnBikeStatVo;
import com.tbit.uqbike.webmanager.business.photo_upload_log.object.vo.PhotoUploadLogVo;
import com.tbit.uqbike.webmanager.business.photo_upload_log.service.PhotoUploadLogService;
import com.tbit.uqbike.webmanager.business.ridelog.object.dto.RideLogCount;
import com.tbit.uqbike.webmanager.dao.core.AccountDao;
import com.tbit.uqbike.webmanager.dao.core.RideLogDao;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

import javax.validation.constraints.NotEmpty;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author <a href="mailto:zheng.zebiao@tbit.com.cn">zb</a>
 * @since 2024/10/17
 */
@Service
@RequiredArgsConstructor
public class PhotoUploadLogServiceImpl implements PhotoUploadLogService {
    final PhotoUploadLogDao photoUploadLogDao;
    final AccountDao accountDao;
    final RideLogDao rideLogDao;

    @Override
    public List<PhotoUploadLog> getList(List<Integer> accountIdList, Integer returnType, Integer result, String orderNO, String userCode, Date startTime, Date endTime, String phone) {
        return photoUploadLogDao.selectList(buildListWrapper(accountIdList, returnType, result, orderNO, userCode, startTime, endTime, phone));
    }

    @Override
    public PageResult<PhotoUploadLogVo> getPage(Integer pageNO, Integer rowCount, List<Integer> accountIdList, Integer returnType, Integer result, String orderNO, String userCode, Date startTime, Date endTime, String phone) {
        Page<PhotoUploadLog> page = photoUploadLogDao.selectPage(new Page<>(pageNO, rowCount),
                buildListWrapper(accountIdList, returnType, result, orderNO, userCode, startTime, endTime, phone));

        return new PageResult<>(pageNO, rowCount, page.getTotal(), (int) page.getPages(), transform(page.getRecords(), accountIdList));
    }

    private QueryWrapper<PhotoUploadLog> buildListWrapper(@NotEmpty List<Integer> accountIdList, Integer returnType, Integer result, String orderNO, String userCode, Date startTime, Date endTime, String phone) {
        return Wrappers.<PhotoUploadLog>query()
                .in("accountId", accountIdList)
                .eq(returnType != null, "returnType", returnType)
                .eq(result != null, "result", result)
                .eq(orderNO != null, "orderNO", orderNO)
                .eq(userCode != null, "userCode", userCode)
                .ge(startTime != null, "addTime", startTime)
                .le(endTime != null, "addTime", endTime)
                .eq(phone != null, "phone", phone)
                .orderByDesc("addTime");
    }

    public List<PhotoUploadLogVo> transform(List<PhotoUploadLog> list, List<Integer> accountIdList) {
        Map<Integer, String> accountNameMap = accountDao.getByAccountIds(accountIdList).stream()
                .collect(Collectors.toMap(Account::getAccountId, Account::getName));

        Map<String, Date> orderTimeMap = list.isEmpty() ? Collections.emptyMap() : rideLogDao.getListByOrderNOs(list.stream()
                        .map(PhotoUploadLog::getOrderNO)
                        .collect(Collectors.toList())).stream()
                .collect(Collectors.toMap(RideLog::getOrderNO, RideLog::getStartTime));

        return list.stream()
                .map(log -> PhotoUploadLogVo.of(log,
                                accountNameMap.get(log.getAccountId()),
                                orderTimeMap.get(log.getOrderNO())
                        )
                )
                .collect(Collectors.toList());
    }

    @Override
    public List<PhotoReturnBikeStatVo> getStat(List<Integer> accountIdList, Date startTime, Date endTime) {
        List<PhotoReturnBikeStatVo> stats = photoUploadLogDao.selectStat(accountIdList, startTime, endTime); // 缺少accountName和totalOrderCount

        // 填充accountName
        Map<Integer, String> accountNameMap = accountDao.getByAccountIds(accountIdList).stream()
                .collect(Collectors.toMap(Account::getAccountId, Account::getName));
        stats.forEach(s -> s.setAccountName(accountNameMap.get(s.getAccountId())));

        // 填充totalOrderCount
        List<String> dates = stats.stream()
                .map(PhotoReturnBikeStatVo::getDate)
                .distinct()
                .collect(Collectors.toList());
        List<RideLogCount> counts = rideLogDao.selectTotalCountByAccountIdAndDate(accountIdList, startTime, endTime);
        stats.forEach(s -> s.setTotalOrderCount(counts.stream()
                .filter(s2 -> s2.getDate().equals(s.getDate()) && s2.getAccountId().equals(s.getAccountId()))
                .map(RideLogCount::getTotalOrderCount)
                .findFirst()
                .orElse(0)
        ));

        return stats;
    }
}
